Mode (Time of Day)¶
Purpose¶
This is an example script that can be modified to suit your implementation. It
will create a rule that will adjust a StringItem named Mode
based on the
time of day. Your modes are configured in configuration.mode_dict
. Each
Mode
can be configured with Times and/or Channels. If both are used, the
first one that occurs will trigger the Mode
. If just a Time is used, the
Mode
will be set after saving the script or an openHAB restart. If a
Channel is used, you will need to wait for the next trigger or manually update
the``Mode``. If the Mode
Item is manually changed to a state that is not a
key found in the configuration.mode_dict
, such as Party
, the
Mode
will not be updated automatically and will need to be manually changed
back to a mode in the dict for the automation to take pver again.
Requires¶
A
Mode
Item (the script will create it for you, if it does not exist)The
mode_dict
OrderedDict added toconfiguration.py
and populated with times for your modes
from core.rules import rule
from core.triggers import when
import configuration
reload(configuration)
from configuration import mode_dict
from core.items import add_item
try:
from org.openhab.core.thing import ChannelUID
except:
from org.eclipse.smarthome.core.thing import ChannelUID
from org.joda.time import DateTime, Interval
if not itemRegistry.getItems("Mode"):
add_item("Mode", item_type="String", label="Mode [%s]", category="House")
def mode_trigger_generator(mode_dict):
def generated_triggers(function):
for mode in list(mode_dict.keys()):
if mode_dict[mode].get("second") is not None and mode_dict[mode].get("minute") is not None and mode_dict[mode].get("hour") is not None:
when("Time cron {} {} {} * * ?".format(mode_dict[mode]["second"], mode_dict[mode]["minute"], mode_dict[mode]["hour"]))(function)
if mode_dict[mode].get("channel") is not None and mode_dict[mode].get("event") is not None:
when("Channel {} triggered {}".format(mode_dict[mode]["channel"], mode_dict[mode]["event"]))(function)
return function
return generated_triggers
@rule("Update Mode")
@when("System started")
@mode_trigger_generator(mode_dict)
def update_mode(event):
last_mode_of_day = mode_dict.items()[-1][0]
new_mode = last_mode_of_day
for i, (mode, value) in enumerate(mode_dict.iteritems()):
if mode != last_mode_of_day:
if event is None and mode_dict[mode].get("hour") is not None and Interval(
DateTime.now().withTime(
value["hour"],
value["minute"],
value["second"],
0
),
DateTime.now().withTime(
mode_dict.items()[i + 1][1].get("hour", value["hour"]),
mode_dict.items()[i + 1][1].get("minute", value["minute"] + 1),
mode_dict.items()[i + 1][1].get("second", value["second"]),
0
)
).contains(DateTime.now()):
new_mode = mode
break
elif hasattr(event, "channel") and mode_dict[mode].get("channel") is not None and event.channel == ChannelUID(mode_dict[mode].get("channel")) and event.event == mode_dict[mode].get("event"):
new_mode = mode
break
if items["Mode"] != StringType(new_mode) and (str(items["Mode"]) in mode_dict.keys() or isinstance(items["Mode"], UnDefType)):
update_mode.log.debug("Mode changed from [{}] to [{}]".format(items["Mode"], new_mode))
events.sendCommand("Mode", new_mode)
else:
update_mode.log.debug("Job ran but current Mode [{}] did not need to be changed: [{}]".format(items["Mode"], new_mode))